package com.pie4cloud.pie.job.executor.utils;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class PathUtils {

	public static  String repalceTime(String path,Date date) {

		if(StringUtils.isBlank(path)) {
			return path;
		}
		int beginIndex = StringUtils.indexOf(path, "${");
		int endIndex = StringUtils.indexOf(path, "}");

		if(beginIndex == -1 || endIndex == -1 || beginIndex >= endIndex) {
			return path;
		}else {
			String timeParrent = StringUtils.substring(path, beginIndex + 2, endIndex);
			String time = DateFormatUtils.format(date, timeParrent);
			path = StringUtils.replace(path,("${"+timeParrent+"}"),time);
			beginIndex = StringUtils.indexOf(path, "${");
			endIndex = StringUtils.indexOf(path, "}");
			if(beginIndex != -1 && endIndex != -1 && beginIndex < endIndex) {
				return repalceTime(path,date);
			}
		}
		return path;
	}

	public static List<String> decodePathReg(String path) {

		List<String> paths = new ArrayList<>();
		List<String> regList = new ArrayList<>();
		String tempPath = findRegs(path,regList,0);
		List<String[]> descartes = descartes(regList);
		for (int i = 0; i < descartes.size(); i++) {
			String[] regs = descartes.get(i);
			String fullPath = tempPath;
			for (int j = 0; j < regs.length;j++) {
				fullPath = StringUtils.replace(fullPath,"$"+j , regs[j]);
			}
			paths.add(fullPath);
		}
		if(paths.isEmpty()) {
			paths.add(path);
		}
		return paths;
	}

	private static String findRegs(String path,List<String> regArrays,int index) {

		if(StringUtils.isBlank(path)) {
			return path;
		}
		int beginIndex = StringUtils.indexOf(path, "(");
		int endIndex = StringUtils.indexOf(path, ")");

		if(beginIndex == -1 || endIndex == -1 || beginIndex >= endIndex) {
			return path;
		} else {
			String reg = StringUtils.substring(path,beginIndex+1,endIndex);
			path = StringUtils.replaceOnce(path,("("+reg+")"),"$"+index);
			regArrays.add(reg);
			index++;
			return findRegs(path,regArrays,index);
		}
	}

	private static List<String[]> descartes(List<String> regs) {
		List<String[]> tempList = new ArrayList<>();
		for (String reg : regs) {
			List<String> regList = Arrays.asList(StringUtils.split(reg,"\\|"));
			if (tempList.isEmpty()) {
				for (int i = 0; i < regList.size(); i++) {
					tempList.add(new String[]{StringUtils.trim(regList.get(i))});
				}
			} else {
				tempList = tempList.stream().flatMap(item -> regList.stream().map(item2 -> org.bouncycastle.util.Arrays.append(item,StringUtils.trim(item2)))).collect(Collectors.toList());
			}
		}
		return tempList;
	}


	public static String parse(String regPath,Map<String,String> resultData,Map<String,String> decodeData)
	{
		String pattern = "\\$\\{(.+?)\\}";
		Pattern p = Pattern.compile(pattern);
		Matcher m = p.matcher(regPath);
		StringBuffer sb = new StringBuffer();
		while (m.find())
		{
			String key = m.group(1);
			String value = getValue(resultData,decodeData,key);
			m.appendReplacement(sb, value == null ? "" : value);
		}
		m.appendTail(sb);
		return StringUtils.isBlank(sb)?null:sb.toString();
	}

	public static void dealIgnoreKeys(Map<String,String> decodeInfo,Map<String,String> commonMap) {
		Map<String,String> result = new HashMap<>();
		for (Map.Entry<String,String> entry:
			 decodeInfo.entrySet()) {
			if(StringUtils.contains(entry.getValue(),"$")) {
				result.put(entry.getKey(),parse(entry.getValue(),commonMap,new HashMap<>()));
			}
		}
		decodeInfo.putAll(result);
	}

	private static String getValue(Map<String,String> resultData,Map<String,String> decodeData,String key) {

		if (resultData == null || resultData.isEmpty()) {
			if(decodeData == null) {
				return null;
			}else {
				return decodeData.get(key);
			}
		}else {
			String value = resultData.get(key);
			return value == null?getValue(null,decodeData,key):value;
		}
	}



	public static void main(String[] args) {
//		List<String[]> descartes = descartes("111 | 112|113", "211| 212","311|312|313");
//		System.out.println(descartes);
//		String path = "/a/b/(111|222|333)/(444|555)";
//		List<String> list = new ArrayList<>();
//		path = findRegs(path, list, 0);
//		System.out.println(path);
//		List<String> list = decodePathReg(path);
//		System.out.println(list);

		HashMap<String, String> map = new HashMap<>();
		map.put("fileName","123");
		String parse = parse("D:/CMADAAS/DATA/HOR/${fileName}", map, new HashMap<>());
		System.out.println(parse);
	}
}
